package me.jiatao.plugindemo;

import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

import dalvik.system.DexClassLoader;
import okio.BufferedSource;
import okio.Okio;
import okio.Source;

/**
 * Created by JiaTao on 2018/11/16.
 * Email: 535318720@qq.com
 * Version: 1.0
 * Description:
 */
public class AssetUtils {

    private static final String TAG = "AssetUtils";

    public static AssetManager sAssetManager;
    public static Resources sResources;
    private static HashMap<String, PluginInfo> pluginInfos;

    static {
        pluginInfos = new HashMap<>();
    }

    /**
     * 获取插件
     *
     * @param apkName
     */
    public static void copyAssetsPlugin2Files(Context context, String apkName) {

        Log.e(TAG, "" + context.getFileStreamPath(apkName));

        AssetManager assets = context.getAssets();
        InputStream inputStream = null;
        try {
            inputStream = assets.open(apkName);
            Source source = Okio.source(inputStream);
            BufferedSource buffer = Okio.buffer(source);
            buffer.readAll(Okio.sink(context.getFileStreamPath(apkName)));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 构造apk对应的classLoader
     *
     * @param context
     * @param apkName
     */
    public static void extractInfo(Context context, String apkName) {
        File apkPath = context.getFileStreamPath(apkName);
        DexClassLoader dexClassLoader = new DexClassLoader(
                apkPath.getAbsolutePath(),
                context.getDir("dex", Context.MODE_PRIVATE).getAbsolutePath(),
                null,
                context.getClassLoader());

        PluginInfo pluginInfo = new PluginInfo(apkPath.getAbsolutePath(), dexClassLoader);
        pluginInfos.put(apkName, pluginInfo);
    }

    /**
     * 根据插件路径构建AssetManager
     *
     * @param context
     * @param apkName
     */
    public static void addAssetPath(Context context, String apkName) {
        try {
            AssetManager assetManager = AssetManager.class.newInstance();
            Method addAssetPath = assetManager.getClass().getDeclaredMethod("addAssetPath", String.class);
            addAssetPath.invoke(assetManager, pluginInfos.get(apkName).getDexPath());

            sAssetManager = assetManager;
            sResources = new Resources(assetManager,
                    context.getResources().getDisplayMetrics(),
                    context.getResources().getConfiguration());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据插件名称获取插件信息
     *
     * @param apkName
     * @return
     */
    public static PluginInfo getPluginInfo(String apkName) {
        if (pluginInfos.containsKey(apkName)) {
            return pluginInfos.get(apkName);
        }

        return null;
    }
}
